package cn.iocoder.yudao.module.of.service.documentinfo;

import cn.hutool.core.date.DateTime;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
import cn.iocoder.yudao.module.of.controller.admin.meetingInfo.vo.MeetingInfoSaveReqVO;
import cn.iocoder.yudao.module.of.controller.admin.meetingInfo.vo.MeetingTaskRespVO;
import cn.iocoder.yudao.module.of.dal.dataobject.meetingInfo.MeetingInfoDO;
import cn.iocoder.yudao.module.of.dal.dataobject.taskgenuser.TaskGenUserDO;
import cn.iocoder.yudao.module.of.dal.dataobject.taskinfo.TaskInfoDO;
import cn.iocoder.yudao.module.of.dal.mysql.taskgenuser.TaskGenUserMapper;
import cn.iocoder.yudao.module.of.dal.mysql.taskinfo.TaskInfoMapper;
import cn.iocoder.yudao.module.of.service.meetingInfo.MeetingInfoService;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.stream.Collectors;

import cn.iocoder.yudao.module.of.controller.admin.documentinfo.vo.*;
import cn.iocoder.yudao.module.of.dal.dataobject.documentinfo.DocumentInfoDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.of.dal.mysql.documentinfo.DocumentInfoMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.of.enums.ErrorCodeConstants.*;

/**
 * 公文信息 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
public class DocumentInfoServiceImpl implements DocumentInfoService {

    @Resource
    private DocumentInfoMapper documentInfoMapper;
    @Resource
    private FileMapper fileMapper;
    @Resource
    private TaskInfoMapper taskInfoMapper;
    @Resource
    private MeetingInfoService meetingInfoService;
    @Resource
    private DeptMapper deptMapper;
    @Resource
    private TaskGenUserMapper taskGenUserMapper;

    @Override
    public Long createDocumentInfo(DocumentInfoSaveReqVO createReqVO) {
        // 插入
        DocumentInfoDO documentInfo = BeanUtils.toBean(createReqVO, DocumentInfoDO.class);
        Long mainRespDeptId = documentInfo.getMainRespDeptId();
        if(mainRespDeptId != null) {
            DeptDO deptDO = deptMapper.selectById(mainRespDeptId);
            if (deptDO != null) {
                //获取部门负责人
                Long leaderUserId = deptDO.getLeaderUserId();
                if (leaderUserId == null) {
                    leaderUserId = deptDO.getRespLeaderUserId();
                }
                documentInfo.setMainRespDeptId(mainRespDeptId);
                documentInfo.setMainRespDeptName(deptDO.getName());
                documentInfo.setMainRespUserId(leaderUserId);
                documentInfo.setTaskGenUserId(-1l);
            }
        }

        documentInfoMapper.insert(documentInfo);

        // 返回
        return documentInfo.getId();
    }

    @Override
    public void updateDocumentInfo(DocumentInfoSaveReqVO updateReqVO) {
        // 校验存在
        validateDocumentInfoExists(updateReqVO.getId());
        // 更新
        DocumentInfoDO updateObj = BeanUtils.toBean(updateReqVO, DocumentInfoDO.class);
        Long mainRespDeptId = updateReqVO.getMainRespDeptId();
        if(mainRespDeptId != null) {
            DeptDO deptDO = deptMapper.selectById(mainRespDeptId);
            if (deptDO != null) {
                //获取部门负责人
                Long leaderUserId = deptDO.getLeaderUserId();
                if (leaderUserId == null) {
                    leaderUserId = deptDO.getRespLeaderUserId();
                }
                updateObj.setId(updateReqVO.getId());
                updateObj.setMainRespDeptId(mainRespDeptId);
                updateObj.setMainRespDeptName(deptDO.getName());
                updateObj.setMainRespUserId(leaderUserId);
                updateObj.setTaskGenUserId(-1l);
            }
        }

        documentInfoMapper.updateById(updateObj);
    }

    @Override
    public void sendDept(DocumentInfoSaveReqVO updateReqVO) {
        // 校验存在
        validateDocumentInfoExists(updateReqVO.getId());
        Long mainRespDeptId = updateReqVO.getMainRespDeptId();
        DocumentInfoDO updateObj = BeanUtils.toBean(updateReqVO, DocumentInfoDO.class);
        if(mainRespDeptId != null) {
            DeptDO deptDO = deptMapper.selectById(mainRespDeptId);
            if (deptDO != null) {
                //获取部门负责人
                Long leaderUserId = deptDO.getLeaderUserId();
                if (leaderUserId == null) {
                    leaderUserId = deptDO.getRespLeaderUserId();
                }
                updateObj.setId(updateReqVO.getId());
                updateObj.setMainRespDeptId(mainRespDeptId);
                updateObj.setMainRespDeptName(deptDO.getName());
                updateObj.setMainRespUserId(leaderUserId);
                updateObj.setTaskGenUserId(-1l);
            }
        }

        if(updateObj.getTaskGenUserId() != null){
            TaskGenUserDO genUserDO = new TaskGenUserDO();
            genUserDO.setTaskGenUserId(updateObj.getTaskGenUserId() );
            genUserDO.setTaskType(2);//类型会议
            genUserDO.setMeetingId(updateReqVO.getId());
            taskGenUserMapper.insert(genUserDO);
        }
        documentInfoMapper.updateById(updateObj);
    }

    @Override
    public void deleteDocumentInfo(Long id) {
        // 校验存在
        validateDocumentInfoExists(id);
        // 删除
        documentInfoMapper.deleteById(id);
    }

    private void validateDocumentInfoExists(Long id) {
        if (documentInfoMapper.selectById(id) == null) {
            throw exception(DOCUMENT_INFO_NOT_EXISTS);
        }
    }

    @Override
    public DocumentInfoDO getDocumentInfo(Long id) {
        return documentInfoMapper.selectById(id);
    }

    @Override
    public PageResult<DocumentInfoRespVO> getDocumentInfoPage(DocumentInfoPageReqVO pageReqVO) {

        MPJLambdaWrapperX<DocumentInfoDO> queryWrapper = new MPJLambdaWrapperX<>();
        //获取MeetingInfoDO 表的别名
        String alias = queryWrapper.getAlias();
        queryWrapper.likeIfPresent(DocumentInfoDO::getDocCode, pageReqVO.getDocCode())
                .betweenIfPresent(DocumentInfoDO::getReceiptDocDate, pageReqVO.getReceiptDocDate());
        queryWrapper.and(wrap->wrap.eq(DocumentInfoDO::getMainRespUserId, WebFrameworkUtils.getLoginUserId())
                .or().eq(DocumentInfoDO::getTaskGenUserId,WebFrameworkUtils.getLoginUserId())
                .or().eq(DocumentInfoDO::getCreator,WebFrameworkUtils.getLoginUserId())
        );
        if(pageReqVO.getStatus() != null){
            //未开始
            if(pageReqVO.getStatus() ==1){
                queryWrapper.gtIfPresent(MeetingInfoDO::getStartTime,new DateTime());
            }else  if(pageReqVO.getStatus() ==2){
                //进行中
                queryWrapper.leIfPresent(MeetingInfoDO::getStartTime,new DateTime())
                        .geIfPresent(MeetingInfoDO::getEndTime,new DateTime());
            }else if(pageReqVO.getStatus() ==3){
                //已结束
                queryWrapper.ltIfPresent(MeetingInfoDO::getEndTime,new DateTime());
            }

        }
        if(pageReqVO.getStatus() != null){
            //任务跟进中
            queryWrapper.exists("select 1 from of_task_info tsk where "+alias+".id = ts.document_id " +
                    " and ts.status = "+pageReqVO.getStatus());
        }
        PageResult<DocumentInfoDO> pageResult = documentInfoMapper.selectPage(pageReqVO, queryWrapper);
        List<DocumentInfoDO> list = pageResult.getList();
        List<DocumentInfoRespVO> collect = list.stream().map(item -> {
            DocumentInfoRespVO documentInfoRespVO = BeanUtils.toBean(item, DocumentInfoRespVO.class);
            //获取会议日程附件
            Set<Long> attachs = item.getAttachs();
            if(attachs != null && !attachs.isEmpty()) {
                List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, attachs);
                if (!fileDOS.isEmpty()) {
                    documentInfoRespVO.setAttachList(fileDOS);
                }
            }
            MPJLambdaWrapperX<TaskInfoDO> taskWrapper = new MPJLambdaWrapperX<>();
            taskWrapper.eq(TaskInfoDO::getDocumentId,item.getId())
                    .eq(TaskInfoDO::getTaskLevel,1);
            if(pageReqVO.getStatus() != null){
                taskWrapper.eq(TaskInfoDO::getStatus,pageReqVO.getStatus());
            }
            List<TaskInfoDO> taskInfoDOS = taskInfoMapper.selectList(taskWrapper);
            List<MeetingTaskRespVO> taskRespList = meetingInfoService.encapTask(taskInfoDOS);
            int closedNum = 0;
            Boolean isEdit = true;
            for(TaskInfoDO task:taskInfoDOS){
                //完成任务
                if(task.getStatus() != null && task.getStatus() == 99){
                    closedNum +=1;
                }
                // getStatus ==1 任务待确认， 别的状态 都是 确认后的状态
                if(task.getStatus() != null && task.getStatus() != 1 && isEdit){
                    isEdit = false;
                }
            }
            documentInfoRespVO.setIsEdit(isEdit);
            //任务数
            documentInfoRespVO.setTaskNum(taskRespList.size());
            //完成任务数
            documentInfoRespVO.setClosedTaskNum(closedNum);
            documentInfoRespVO.setTaskList(taskRespList);
            return documentInfoRespVO;

        }).collect(Collectors.toList());
        PageResult<DocumentInfoRespVO> result = new PageResult<>();
        result.setList(collect).setTotal(pageResult.getTotal());
        return result;
    }

}